package chap_06.customer_collector;

import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.IntStream;

public class Run_05 {
    @Test
    public void run_01() {
        Map<Boolean, List<Integer>> collect = IntStream.rangeClosed(2, 100).boxed().collect(new PrimeNumberCollector());
        System.out.println(collect);
    }

    @Test
    public void run_02() {
        HashMap<Boolean, List<Integer>> collect = IntStream.rangeClosed(2, 100).boxed().collect(
                () -> new HashMap<Boolean, List<Integer>>() {
                            {
                                put(true, new ArrayList<Integer>());
                                put(false, new ArrayList<Integer>());
                            }
                        }
                ,
                (acc, condidate) -> {
                    acc.get(isPrime(acc.get(true), condidate)).add(condidate);
                },
                (map1, map2) -> {
                    map1.get(true).addAll(map2.get(true));
                    map1.get(false).addAll(map2.get(false));
                }
        );

        System.out.println(collect);
    }

    public boolean isPrime(List<Integer> primes, int candidate) {
        int candidateRoot = (int) Math.sqrt((double) candidate);
        return takeWhile(primes, i -> i <= candidateRoot).stream().noneMatch(p -> candidate % p == 0);
    }

    public <A> List<A> takeWhile(List<A> list, Predicate<A> p) {
        int i = 0;
        for (A item : list) {
            if (!p.test(item)) {
                return list.subList(0, i);
            }
            i++;
        }
        return list;

    }
}
